Ignore layout shift when visibility:hidden becomes visible We should ignore layout shift if the object was ineligible for layout shift tracking during the previous paint invalidation. Add LayoutObject::ShouldSkipNextLayoutShiftTracking() and set it during paint invalidation if the object is ineligible for layout shift tracking. In the next paint invalidation, if the flag is true, skip layout shift tracking and reset the flag. This also applies to content-visibility:auto for which we cleared LayoutBox's previous size to prevent layout shift tracking for the next cycle. The new flag is basically equivalent to the old method, but also covers more cases, e.g. the old method would fail if the object had visual overflow because PreviousPhysicalVisualOverflowRect() was not based on PreviousSize() and empty. Bug: 1152869 Change-Id: I000489dd8093dab8d2ab3605ad4ce3bd39fd11b0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2591367 Reviewed-by: Chris Harrelson <chrishtr@chromium.org> Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org> Cr-Commit-Position: refs/heads/master@{#837627} 
diff --git a/layout-instability/visibility-hidden-layout-and-visible.html b/layout-instability/visibility-hidden-layout-and-visible.html new file mode 100644 index 0000000..3fea6bb --- /dev/null +++ b/layout-instability/visibility-hidden-layout-and-visible.html 
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>Layout Instability: visibility:hidden change with layout</title> +<link rel="help" href="https://wicg.github.io/layout-instability/" /> +<div id="target" style="position: absolute; top: 0; width: 200px; height: 200px; visibility: hidden"></div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/util.js"></script> +<script> + +promise_test(async () => { + const watcher = new ScoreWatcher; + + // Wait for the initial render to complete. + await waitForAnimationFrames(2); + + // Shift target, for which no shift should be reported because it's hidden. + target.style.top = '200px'; + target.style.visibility = 'visible'; + + await waitForAnimationFrames(2); + // No shift should be reported. + assert_equals(watcher.score, 0); + + // Shift again, for which shift should be reported. + target.style.top = '300px'; + + await watcher.promise; + const expectedScore = computeExpectedScore(200 * (200 + 100), 100); + assert_equals(watcher.score, expectedScore); + +}, 'visibility:hidden change with layout'); + +</script>